package com.ruoyi.caigou.service.impl;

import com.ruoyi.activiti.api.RemoteActivitiService;
import com.ruoyi.caigou.mapper.BuyBackReqDetailMapper;
import com.ruoyi.caigou.mapper.BuyBackReqMapper;
import com.ruoyi.caigou.service.IBuyBackReqService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteStockInDetailService;
import com.ruoyi.system.api.constants.BuyBackOrderConstants;
import com.ruoyi.system.api.domain.caigou.BuyBackReq;
import com.ruoyi.system.api.domain.caigou.BuyBackReqDetail;
import com.ruoyi.system.api.domain.store.StockInDetail;
import com.ruoyi.system.api.dto.ActApprovalDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

import static com.ruoyi.common.core.utils.PageUtils.startPage;

/**
 * 采购退货申请单Service业务层处理
 *
 * @author wl
 * @date 2024-10-28
 */
@Service
@Slf4j
public class BuyBackReqServiceImpl implements IBuyBackReqService {
    @Autowired
    private BuyBackReqMapper buyBackReqMapper;

    @Autowired
    private BuyBackReqDetailMapper buyBackReqDetailMapper;

    @Autowired
    private RemoteActivitiService remoteActivitiService;

    @Autowired
    private RemoteStockInDetailService remoteStockInDetailService;

    /**
     * 查询采购退货申请单
     *
     * @param id 采购退货申请单主键
     * @return 采购退货申请单
     */
    @Override
    public BuyBackReq selectBuyBackReqById(Integer id) {
        return buyBackReqMapper.selectBuyBackReqById(id);
    }

    /**
     * 查询采购退货申请单列表
     *
     * @param buyBackReq 采购退货申请单
     * @return 采购退货申请单
     */
    @Override
    public List<BuyBackReq> selectBuyBackReqList(BuyBackReq buyBackReq) {
        startPage();
        List<BuyBackReq> buyBackReqList = buyBackReqMapper.selectBuyBackReqList(buyBackReq);
        log.info("BuyBackReqServiceImpl selectBuyBackReqList buyBackReqList:{}", buyBackReqList);
        return buyBackReqList;
    }

    /**
     * 新增采购退货申请单
     *
     * @param buyBackReq 采购退货申请单
     * @return 结果
     */
    @Transactional
    public AjaxResult insertBuyBackReq(BuyBackReq buyBackReq) {
        //校验单据编号
        if (StringUtils.isBlank(buyBackReq.getCode())) {
            return AjaxResult.error("单据编号不能为空");
        }
        int codeNum = buyBackReqMapper.selectBuyBackReqCountByCode(buyBackReq.getCode());
        if (codeNum > 0) {
            return AjaxResult.error("单据编号已存在");
        }

        //校验供应商
        if (buyBackReq.getSupplierId() == null) {
            return AjaxResult.error("供应商不能为空");
        }

        //校验采购入库单
        if (buyBackReq.getStockInId() == null) {
            return AjaxResult.error("采购入库单不能为空");
        }

        //获取采购入库详情列表进行入库数量校验
        R<List<StockInDetail>> stockInDetailR = remoteStockInDetailService.getStockInDetailListByStockInId(buyBackReq.getStockInId());
        log.info("insertBuyBackReq stockInDetailR:{}", stockInDetailR);
        if (stockInDetailR.getCode() != HttpStatus.OK.value()) {
            return AjaxResult.error("获取采购入库单明细失败");
        }
        List<StockInDetail> stockInDetailList = stockInDetailR.getData();

        //校验单据日期
        if (buyBackReq.getOrderDate() == null) {
            return AjaxResult.error("单据日期不能为空");
        }

        //采购退货申请明细
        List<BuyBackReqDetail> buyBackReqDetailList = buyBackReq.getBuyBackReqDetailList();
        if (buyBackReqDetailList == null || buyBackReqDetailList.isEmpty()) {
            return AjaxResult.error("退货明细不能为空");
        }

        int allOutStock = 0;
        //采购退货总数=采购明细数量总和
        for (BuyBackReqDetail buyBackReqDetail : buyBackReqDetailList) {
            //校验明细商品
            if (buyBackReqDetail.getGoodsId() == null) {
                return AjaxResult.error("商品不能为空");
            }

            //校验明细退货数量是否为空
            if (buyBackReqDetail.getQuantity() == null) {
                return AjaxResult.error("退货数量不能为空");
            }

            //校验明细退货数量是否大于0
            if (buyBackReqDetail.getQuantity() <= 0) {
                return AjaxResult.error("退货数量必须大于0");
            }

            //获取采购入库单明细，校验采购入库数量大于采购退货数量
            for (StockInDetail stockInDetail : stockInDetailList) {
                if (buyBackReqDetail.getGoodsId().equals(stockInDetail.getGoodsId()) && buyBackReqDetail.getQuantity() > stockInDetail.getNum()) {
                    return AjaxResult.error("退货数量不能大于采购入库数量");
                }
            }

            allOutStock = allOutStock + buyBackReqDetail.getQuantity();
        }

        //添加初始化状态
        buyBackReq.setAllOutStock(allOutStock);
        buyBackReq.setApprovalResult(BuyBackOrderConstants.APPROVAL_NOT_APPROVED);
        buyBackReq.setCreateBy(SecurityUtils.getUsername());
        buyBackReq.setCreateDate(new Date());
        buyBackReq.setIsDel(0);
        buyBackReq.setIsEffect(0);
        buyBackReq.setIsCancel(0);
        buyBackReq.setIsClose(0);
        buyBackReq.setRealOutStock(0);

        int addNum = buyBackReqMapper.insertBuyBackReq(buyBackReq);
        if (addNum <= 0) {
            return AjaxResult.error("新增失败");
        }
        //插入采购申请详情
        for (BuyBackReqDetail buyBackReqDetail : buyBackReqDetailList) {
            //添加初始化状态
            buyBackReqDetail.setIsDel(0);
            buyBackReqDetail.setCreateBy(SecurityUtils.getUsername());
            buyBackReqDetail.setCreateDate(new Date());
            buyBackReqDetail.setBuyBackReqId(buyBackReq.getId());

            addNum = buyBackReqDetailMapper.insertBuyBackReqDetail(buyBackReqDetail);
            if (addNum <= 0) {
                throw new RuntimeException("新增失败");
            }
        }

        //采购退货申请添加审核任务
        ActApprovalDTO actApprovalDTO = new ActApprovalDTO();
        actApprovalDTO.setProcessDefinitionKey("buyBackReqBPMN");
        actApprovalDTO.setOrderCode(buyBackReq.getCode());
        actApprovalDTO.setTaskName(buyBackReq.getCode() + "采购退货申请");
        actApprovalDTO.setDeptId(103);
        AjaxResult addApprovalAjaxResult = remoteActivitiService.addApproval(actApprovalDTO);
        Integer code = (Integer) addApprovalAjaxResult.get("code");
        if (code != 200) {
            throw new RuntimeException("新增失败");
        }
        log.info("BuyBackReqServiceImpl insertBuyBackReq codeNum:{}", codeNum);
        return AjaxResult.success();
    }

    /**
     * 修改采购退货申请单
     *
     * @param buyBackReq 采购退货申请单
     * @return 结果
     */
    @Override
    public AjaxResult updateBuyBackReq(BuyBackReq buyBackReq) {
        //校验采购退货单id
        if (buyBackReq.getId() == null) {
            return AjaxResult.error("采购退货单id不能为空");
        }

        //采购退货申请明细
        List<BuyBackReqDetail> buyBackReqDetailList = buyBackReq.getBuyBackReqDetailList();
        if (buyBackReqDetailList == null || buyBackReqDetailList.isEmpty()) {
            return AjaxResult.error("退货明细不能为空");
        }

        //获取采购入库详情列表进行入库数量校验
        R<List<StockInDetail>> stockInDetailR = remoteStockInDetailService.getStockInDetailListByStockInId(buyBackReq.getStockInId());
        log.info("updateBuyBackReq stockInDetailR:{}", stockInDetailR);
        if (stockInDetailR.getCode() != HttpStatus.OK.value()) {
            return AjaxResult.error("获取采购入库单明细失败");
        }
        List<StockInDetail> stockInDetailList = stockInDetailR.getData();

        int allOutStock = 0;
        //采购退货总数=采购明细数量总和
        for (BuyBackReqDetail buyBackReqDetail : buyBackReqDetailList) {
            ///校验明细商品
            if (buyBackReqDetail.getGoodsId() == null) {
                return AjaxResult.error("商品不能为空");
            }

            //校验明细退货数量是否为空
            if (buyBackReqDetail.getQuantity() == null) {
                return AjaxResult.error("退货数量不能为空");
            }

            //校验明细退货数量是否大于0
            if (buyBackReqDetail.getQuantity() <= 0) {
                return AjaxResult.error("退货数量必须大于0");
            }

            //获取采购入库单明细，校验采购入库数量大于采购退货数量
            for (StockInDetail stockInDetail : stockInDetailList) {
                if (buyBackReqDetail.getGoodsId().equals(stockInDetail.getGoodsId()) && buyBackReqDetail.getQuantity() > stockInDetail.getNum()) {
                    return AjaxResult.error("退货数量不能大于采购入库数量");
                }
            }
            allOutStock = allOutStock + buyBackReqDetail.getQuantity();
        }

        //设置修改状态
        buyBackReq.setAllOutStock(allOutStock);
        buyBackReq.setModifyBy(SecurityUtils.getUsername());
        buyBackReq.setModifyDate(new Date());

        //删除采购退货申请单明细
        buyBackReqDetailMapper.deleteBuyBackReqDetailByBuyBackReqId(buyBackReq.getId());

        int updNum = buyBackReqMapper.updateBuyBackReq(buyBackReq);
        if (updNum <= 0) {
            throw new RuntimeException("修改失败");
        }
        //插入采购申请详情
        for (BuyBackReqDetail buyBackReqDetail : buyBackReqDetailList) {
            //添加初始化状态
            buyBackReqDetail.setIsDel(0);
            buyBackReqDetail.setCreateBy(SecurityUtils.getUsername());
            buyBackReqDetail.setCreateDate(new Date());
            buyBackReqDetail.setBuyBackReqId(buyBackReq.getId());

            updNum = buyBackReqDetailMapper.insertBuyBackReqDetail(buyBackReqDetail);
            if (updNum <= 0) {
                throw new RuntimeException("修改失败");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除采购退货申请单
     *
     * @param ids 需要删除的采购退货申请单主键
     * @return 结果
     */
    @Transactional
    public AjaxResult deleteBuyBackReqByIds(Integer[] ids) {
        //未审核状态的采购退货申请单可以删除
        List<BuyBackReq> buyBackReqList = buyBackReqMapper.selectBuyBackReqListByIds(ids);
        for (BuyBackReq buyBackReq : buyBackReqList) {
            if (buyBackReq.getApprovalResult() != 3) {
                return AjaxResult.error("只能删除驳回的采购退货申请单");
            }
        }
        buyBackReqDetailMapper.deleteBuyBackReqDetailByBuyBackReqIds(ids);
        int delNum = buyBackReqMapper.deleteBuyBackReqByIds(ids);
        if (delNum <= 0) {
            throw new RuntimeException("删除失败");
        }
        return AjaxResult.success();
    }

    /**
     * 删除采购退货申请单信息
     *
     * @param id 采购退货申请单主键
     * @return 结果
     */
    @Transactional
    public AjaxResult deleteBuyBackReqById(Integer id) {
        //未审核状态的采购退货申请单可以删除
        List<BuyBackReq> buyBackReqList = buyBackReqMapper.selectBuyBackReqListByIds(new Integer[]{id});
        for (BuyBackReq buyBackReq : buyBackReqList) {
            if (buyBackReq.getApprovalResult() != 3) {
                return AjaxResult.error("只能删除未审核的采购退货申请单");
            }
        }
        buyBackReqDetailMapper.deleteBuyBackReqDetailByBuyBackReqId(id);
        int delNum = buyBackReqMapper.deleteBuyBackReqById(id);
        if (delNum <= 0) {
            return AjaxResult.error("删除失败");
        }
        return AjaxResult.success();
    }

    /**
     * @return com.ruoyi.common.core.web.domain.AjaxResult
     * @description 审核采购退货申请单
     * @date 2024/11/5 上午8:17
     * @Param buyBackReq:
     **/
    public AjaxResult updateStatusByCode(BuyBackReq buyBackReq) {
        //校验采购退货需求单编号是否为空
        if (buyBackReq.getCode() == null) {
            return AjaxResult.error("采购退货需求单编号不能为空");
        }
        //设置审核人修改时间修改人
        buyBackReq.setApprovalId(Math.toIntExact(SecurityUtils.getUserId()));
        buyBackReq.setModifyDate(new Date());
        buyBackReq.setModifyBy(SecurityUtils.getUsername());
        buyBackReq.setEffectDate(new Date());
        int updNum = buyBackReqMapper.updateBuyBackReq(buyBackReq);
        if (updNum > 0) {
            AjaxResult.success();
        }
        return AjaxResult.error("修改失败!");
    }

    /**
     * @return com.ruoyi.system.api.domain.caigou.BuyBackReq
     * @description 通过单据编码获取采购退货申请详情
     * @date 2024/11/5 上午8:16
     * @Param code:
     **/
    public BuyBackReq selectBuyBackReqByCode(String code) {
        BuyBackReq buyBackReq = buyBackReqMapper.selectBuyBackReqByCode(code);
        BuyBackReqDetail buyBackReqDetail = new BuyBackReqDetail();
        buyBackReqDetail.setBuyBackReqId(buyBackReq.getId());
        buyBackReq.setBuyBackReqDetailList(buyBackReqDetailMapper.selectBuyBackReqDetailList(buyBackReqDetail));
        return buyBackReq;
    }

    /**
     * @return java.util.List<com.ruoyi.system.api.domain.caigou.BuyBackReqDetail>
     * @description 根据采购退货申请id获取采购退货申请详情
     * @date 2024/11/5 下午10:39
     * @Param buyBackReqId:
     **/
    public List<BuyBackReqDetail> selectBuyBackReqDetailListByBuyBackReqId(Integer buyBackReqId) {
        BuyBackReqDetail buyBackReqDetail = new BuyBackReqDetail();
        buyBackReqDetail.setBuyBackReqId(buyBackReqId);
        return buyBackReqDetailMapper.selectBuyBackReqDetailList(buyBackReqDetail);
    }
}
